<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>

<body>
  <script>

    // 缓存函数
    function cachedFun(fun) {
      let cache = Object.create(null)
      // 实际应用了柯里化/偏函数
      return function (...args) {
        // 在js中, 连续的赋值不会返回bool, 而是返回赋的值
        return cache[args.toString()] || (cache[args.toString()] = fun(...args))
      }
    }

    function sum(...args) {
      // console.log(args.reduce((r, a) => r + a))

      console.log('此时调用了函数, 没有使用缓存')
      return args.reduce((r, a) => r + a)
    }

    let cachedSum = cachedFun(sum)

    console.log(cachedSum(1, 2, 456))


    // 柯里化
    let obj = {
      fqm: 'fqmyysjjd'
    }

    // 假设从别的文件导入的
    let fqm = obj.fqm

    // 假设在本文件内的
    let myObj = {
      // ...
      yy: function (addition, ...args) {
        // 对于现有的结果做一些处理
        return cachedSum(...args) + ': ' + addition
      }
    }

    function foo(addition, fun, ...args) {
      return fun(addition, ...args)
    }

    console.log(foo(fqm, myObj.yy, 1, 2, 456))

    // 使用柯里化, 即参数拆分
    function curryFoo(addition) {
      return fun => {
        return (...args) => fun(addition, ...args)
      }
    }

    console.log(curryFoo(fqm)(myObj.yy)(1, 2, 456))

    let newFoo = curryFoo(fqm)(myObj.yy)
    console.log(newFoo(1, 2, 3))
    console.log(newFoo(1, 2, 5))



    // 偏函数: 柯里化的一种特定的使用方式
    // 传入特殊处理的结果和函数
    function partialFoo(addition, fun) {
      return function (...args) {
        return fun(addition, ...args)
      }
    }

    let newSum = partialFoo(fqm, myObj.yy)

    console.log(newSum(1, 2, 455))


  </script>
</body>

</html>